package com.own.component.sensitive.check;

import com.own.component.common.exception.BusinessSimpleException;
import com.own.component.common.util.encrypt.EncryptUtil;
import com.own.component.common.util.encrypt.model.CustomEncryptKey;
import com.own.component.sensitive.check.entity.SensitiveTokenVo;
import com.own.component.store.core.Store;
import com.own.component.store.core.util.base.RsaKeyUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.UUID;

/**
 * SensitiveTokenUtil
 *
 * @author chenxueli
 * @date 2023-11-09 15:25:00
 */
@Component
public class SensitiveTokenUtil {

    @Resource
    private RsaKeyUtil rsaKeyUtil;
    @Resource
    private Store<String> store;

    /**
     * 获取验证信息的token
     *
     * @param userId   用户id
     * @param runnable 验证信息
     * @return 令牌信息
     */
    public SensitiveTokenVo getToken(Long userId, Runnable runnable) {
        return getToken(userId, null, runnable);
    }

    /**
     * 获取验证信息的token
     *
     * @param userId    用户id
     * @param publicKey 公钥
     * @param runnable  验证信息
     * @return 令牌信息
     */
    public SensitiveTokenVo getToken(Long userId, String publicKey, Runnable runnable) {
        // 执行验证
        runnable.run();
        // 生成令牌信息
        var token = (UUID.randomUUID() + UUID.randomUUID().toString()).replaceAll("-", "");
        // 加密返回
        if (StringUtils.isNotBlank(publicKey)) {
            token = EncryptUtil.RSA.encrypt(token, CustomEncryptKey.builder().publicKey(publicKey).build());
        }
        var key = "w:c:token:" + userId;
        // 存入缓存（1小时有效）
        store.value().set(key, token, Duration.ofHours(1));
        // 封装，返回数据
        return new SensitiveTokenVo(token);
    }

    /**
     * 校验token
     *
     * @param userId     用户id
     * @param token      令牌信息
     * @param encryptKey 加密key
     */
    public void checkToken(Long userId, String token, String encryptKey) {
        // 获取真实的token
        var realToken = rsaKeyUtil.decrypt(encryptKey, token, false);
        var key = "w:c:token:" + userId;
        // 获取缓存中的token
        var cacheToken = store.value().get(key);
        if (StringUtils.isBlank(cacheToken)) {
            throw new BusinessSimpleException("敏感信息修改的令牌不存在");
        }
        if (cacheToken.equals(realToken)) {
            throw new BusinessSimpleException("敏感信息修改的令牌不正确");
        }
        // 删除对应的信息
        store.value().remove(key);
    }

}
